package IC; 
 
import java.io.File; 
 
/** 
 * This class handles the command line operations of the compiler.
 * Design as a singelton Class.
 */ 
public class CmdHandler { 
         
        private static final String USAGE = "Usage: java IC.Compiler <file.ic> [-L</path/to/libic.sig>] [-print-ast] [-dump-symtab] [-print-lir] [-debug]"; 
        private static final String PRINT_AST_FLAG = "-print-ast";         
        private static final String DEBUG_FLAG = "-debug"; 
        private static final String DUMP_SYMTAB = "-dump-symtab";
        private static final String PRINT_LIR = "-print-lir"; 
      
        private String ICFilePath = null; 
        private String ICLibraryFilePath = null; 
        private boolean PrintAST = false; 
        private boolean DumpSymtb = false; 
        private boolean debug = false; 
        private boolean PrintLIR = false; 
      
         
    	private static CmdHandler inst = null;
    	
    	public static boolean HasInstance()
    	{
    		return (inst!=null);
    	}
    	
    	public static void CreateNewInstance(String[] args) throws Exception
    	{
    		if (args == null || args.length < 1 ) 
    			throw new Exception(USAGE);
    		
    		if (!isValidICFile(args[0]))
    			throw new Exception(USAGE);
    		
    		if (args.length > 1 ) 
    		 if (args[1].startsWith("-L")) 
    			 if (!isValidICFile(args[1].substring(2)))
    				 throw new Exception(USAGE);
    		
	    	if (inst==null)
				inst = new CmdHandler(args);
	    	else
	    		throw new Exception("Instance already exist!");
    	}

    	public static CmdHandler Inst() throws Exception
    	{
    		if (inst==null)
    			throw new Exception("Instance is not exist!");
    		return inst;
    	}
    	
    	//C'tor
        private CmdHandler(String[] args) { 
            this.ICFilePath = args[0];          
            for (int i = 1; i < args.length; i++) { 
            	  if (args[i].startsWith("-L")) 
                      this.ICLibraryFilePath = args[i].substring(2);
            	   if (args[i].equals(PRINT_AST_FLAG)) 
                       this.PrintAST = true; 
            	   if (args[i].equals(DUMP_SYMTAB)) 
                       this.DumpSymtb = true;
            	   if (args[i].equals(PRINT_LIR))  
                       this.PrintLIR = true; 
            	   if (args[i].equals(DEBUG_FLAG))  
                       this.debug = true; 
            }                 
        } 
        
        private static boolean isValidICFile(String FilePath) { 
            File f = new File(FilePath); 
            if (!f.isFile() || !(f.getName().endsWith(".ic") || f.getName().endsWith(".sig")))
                    return false;    
            return true; 
        } 
     
        
        /** 
         * return the IC file path. 
         * @return ICFilePath.
         */ 
        public String getICFilePath() { 
                return this.ICFilePath; 
        } 
        
        /** 
         * return the IC Library file path. 
         * @return ICLibraryFilePath.
         */ 
        public String getICLibraryFilePath() { 
                return this.ICLibraryFilePath; 
        } 
         
        /** 
         * check if ICLibraryFilePath exist.
         * @return true if ICLibraryFilePath exist, false otherwise.
         */ 
        public boolean isICLibraryFilePathExist() { 
                return this.ICLibraryFilePath != null; 
        } 
        
        /** 
         * check if print-ast flag requested.
         * @return true if print-ast flag requested, false otherwise.
         */ 
        public boolean isPrintAST() { 
                return this.PrintAST; 
        } 
        
        /** 
         * check if print-lir flag requested.
         * @return true if print-lir flag requested, false otherwise.
         */ 
        public boolean isPrintLIR() { 
                return this.PrintLIR; 
        } 
        
        /** 
         * check if dump-symtab flag requested.
         * @return true if dump-symtab flag requested, false otherwise.
         */ 
        public boolean isDumpSymtb() { 
                return this.DumpSymtb; 
        } 
        
        /** 
         * check if debug flag requested.
         * @return true if debug flag requested, false otherwise.
         */ 
        public boolean isDebug() { 
                return this.debug; 
        } 

} 


